<template>
  <div>
    <a-alert type="warning" show-icon style="margin-bottom: 18px">
      <template #description>
        智能验证码功能已对接阿里云验证码、腾讯云验证码、极验、京东云验证码等平台，支持后台一键切换。
        <a
          href="https://doc.21ds.cn/detail?doc=4731341806141859/4835430784897034"
          target="_blank"
          rel="noopener noreferrer"
          >对接文档</a
        >
      </template>
    </a-alert>
    <div class="table-page-search-wrapper">
      <a-row type="flex" justify="space-between" align="middle">
        <a-col :span="16">
          <a-form layout="inline" :model="listQuery">
            <a-form-item label="搜索项">
              <a-input v-model:value="listQuery.title" placeholder="输入名称搜索..." />
            </a-form-item>
            <a-form-item>
              <a-button type="primary" @click="searchSubmit"> 搜索 </a-button>
            </a-form-item>
            <a-form-item>
              <a-button
                v-permission="{ action: 'del_captcha_batch' }"
                type="primary"
                danger
                :disabled="selectedRowKeys.length === 0"
                @click="deleteSelect"
              >
                <template #icon>
                  <DeleteOutlined />
                </template>
                删除所选
              </a-button>
            </a-form-item>
          </a-form>
        </a-col>
        <a-col :span="8">
          <div style="margin-right: 0px; float: right; display: flex; align-item: center">
            <a-tooltip placement="top">
              <template #title>
                <span>刷新列表</span>
              </template>
              <a-button @click="reloadList">
                <template #icon><SyncOutlined /></template>
              </a-button>
            </a-tooltip>
            <a-button
              v-permission="{ action: 'captcha_add' }"
              type="primary"
              style="margin-left: 12px"
              @click="captcha_add"
            >
              <template #icon><PlusOutlined /></template> 新增验证
            </a-button>
          </div>
        </a-col>
      </a-row>
    </div>
    <a-table
      :columns="columns"
      :rowKey="(record) => record._id"
      :dataSource="dataList.data"
      :loading="loading"
      :pagination="pagination"
      :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
      @change="handleTableChange"
    >
      <template #status="{ text: record }">
        <a-tag
          v-if="record.status == 1"
          color="green"
          style="cursor: pointer"
          @click="changeStatus(0, record)"
          >启用</a-tag
        >
        <a-tag v-if="record.status == 0" style="cursor: pointer" @click="changeStatus(1, record)"
          >未启用</a-tag
        >
      </template>
      <template #action="{ text: record }">
        <a v-permission="{ action: 'captcha_add' }" @click="captcha_edit(record)"
          ><EditOutlined /> 编辑</a
        >
        <a-divider v-permission="{ action: 'captcha_copy' }" type="vertical" />
        <a v-permission="{ action: 'captcha_copy' }" @click="captcha_copy(record)"
          ><CopyOutlined /> 复制</a
        >
        <a-divider v-permission="{ action: 'captcha_del' }" type="vertical" />
        <a
          v-permission="{ action: 'captcha_del' }"
          style="color: red"
          @click="captcha_delete(record)"
          ><DeleteOutlined /> 删除</a
        >
      </template>
    </a-table>
    <a-drawer
      width="45%"
      title="验证详情"
      placement="right"
      :open="drawerShow"
      @close="
        () => {
          drawerShow = false
        }
      "
    >
      <template #extra>
        <a-button
          style="margin-right: 8px"
          @click="
            () => {
              drawerShow = false
            }
          "
          >取消</a-button
        >
        <a-button type="primary" @click="addItem">提交</a-button>
      </template>
      <a-form
        ref="formRef"
        :model="FormState"
        :rules="FormRule"
        :labelCol="labelCol"
        :wrapperCol="wrapperCol"
      >
        <a-form-item label="验证名称" has-feedback required name="title">
          <a-input v-model:value="FormState.title" placeholder="请输入验证名称" />
        </a-form-item>
        <a-form-item label="验证平台" has-feedback required name="platform">
          <a-radio-group v-model:value="FormState.platform" name="platform">
            <a-radio key="jdcloud" value="jdcloud">京东云验证码</a-radio>
            <a-radio key="aliyun" value="aliyun">阿里云验证码</a-radio>
            <a-radio key="tencent" value="tencent">腾讯云验证码</a-radio>
            <a-radio key="geetest" value="geetest">极验</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item label="凭证来源" has-feedback required name="ak_from">
          <a-radio-group v-model:value="FormState.ak_from">
            <a-radio key="platform" value="platform">在[凭证管理]中选择</a-radio>
            <a-radio key="alone" value="alone">单独设置</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item v-if="FormState.ak_from == 'platform'" label="选择凭证" name="ak_id">
          <a-select
            v-model:value="FormState.ak_id"
            show-search
            placeholder="请选择(支持搜索)"
            :default-active-first-option="false"
            :show-arrow="true"
            :filter-option="false"
            :options="akList"
            :fieldNames="{ value: '_id', label: 'title' }"
            @search="searchInput"
          >
            <template #notFoundContent>
              <a-empty
                image="https://img.alicdn.com/imgextra/i3/573804794/O1CN01IO097G1lHhdtoisyG_!!573804794.png"
                :image-style="{
                  height: '90px'
                }"
              >
                <template #description>
                  <view style="color: rgba(0, 0, 0, 0.88); padding-top: 20px">
                    暂无可选项，请先
                    <router-link :to="{ name: 'AkManage' }" target="_blank">添加</router-link>
                  </view>
                </template>
              </a-empty>
            </template>
          </a-select>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'jdcloud' && FormState.ak_from == 'alone'"
          label="Access Key ID"
        >
          <a-input v-model:value="FormState.jdcloud_access_key_id" placeholder="请填写">
            <template #suffix>
              <a href="https://uc.jdcloud.com/account/accesskey" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'jdcloud' && FormState.ak_from == 'alone'"
          label="Access Key Secret"
        >
          <a-input v-model:value="FormState.jdcloud_access_key_secret" placeholder="请填写">
            <template #suffix>
              <a href="https://uc.jdcloud.com/account/accesskey" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item v-if="FormState.platform == 'jdcloud'" label="应用ID">
          <a-input v-model:value="FormState.jdcloud_app_id" placeholder="请填写">
            <template #suffix>
              <a href="https://captcha-console.jdcloud.com/appManagement" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item v-if="FormState.platform == 'jdcloud'" label="场景ID">
          <a-input v-model:value="FormState.jdcloud_scene_id" placeholder="请填写">
            <template #suffix>
              <a href="https://captcha-console.jdcloud.com/sceneManagement" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item v-if="FormState.platform == 'jdcloud'" label="场景密钥">
          <a-input v-model:value="FormState.jdcloud_scene_secret" placeholder="请填写">
            <template #suffix>
              <a href="https://captcha-console.jdcloud.com/sceneManagement" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item v-if="FormState.platform == 'jdcloud'" label="客户端类型">
          <a-radio-group v-model:value="FormState.jdcloud_client_type" name="jdcloud_client_type">
            <a-radio key="pc" value="pc">PC网站</a-radio>
            <a-radio key="m" value="m">H5网站</a-radio>
            <a-radio key="wxmapp" value="wxmapp">微信小程序</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'geetest' && FormState.ak_from == 'alone'"
          label="验证 ID"
        >
          <a-input v-model:value="FormState.geetest_id" placeholder="请填写">
            <template #suffix>
              <a href="https://console.geetest.com/sensbot/management" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'geetest' && FormState.ak_from == 'alone'"
          label="验证 Key"
        >
          <a-input v-model:value="FormState.geetest_key" placeholder="请填写">
            <template #suffix>
              <a href="https://console.geetest.com/sensbot/management" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item v-if="FormState.platform == 'geetest'" label="验证样式">
          <a-radio-group v-model:value="FormState.geetest_type" name="geetest_type">
            <a-radio key="popup" value="popup">弹出式</a-radio>
            <a-radio key="float" value="float">浮动式</a-radio>
            <a-radio key="bind" value="bind">隐藏按钮类型</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item v-if="FormState.platform == 'geetest'" label="验证按钮大小">
          <a-input
            v-model:value="FormState.geetest_style_width"
            placeholder="请填写，如：300px或100%"
            prefix="宽"
            style="width: 48%"
          />
          <a-input
            v-model:value="FormState.geetest_style_height"
            placeholder="请填写，如：300px或100%"
            prefix="高"
            style="width: 48%; margin-left: 4%"
          />
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'aliyun' && FormState.ak_from == 'alone'"
          label="AccessKeyId"
          name="aliyun_key_id"
        >
          <a-input v-model:value="FormState.aliyun_key_id" placeholder="请填写密钥ID">
            <template #suffix>
              <a href="https://ram.console.aliyun.com/manage/ak" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'aliyun' && FormState.ak_from == 'alone'"
          label="AccessKeySecret"
          name="aliyun_key_secret"
        >
          <a-input v-model:value="FormState.aliyun_key_secret" placeholder="请填写访问密钥">
            <template #suffix>
              <a href="https://ram.console.aliyun.com/manage/ak" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'aliyun'"
          label="验证码Appkey"
          name="aliyun_captcha_key"
        >
          <a-input v-model:value="FormState.aliyun_captcha_key" placeholder="请填写验证码Appkey">
            <template #suffix>
              <a href="https://yundun.console.aliyun.com/?p=afs#/person-machine" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'aliyun'"
          label="验证码宽度"
          name="aliyun_style_width"
        >
          <a-input
            v-model:value="FormState.aliyun_style_width"
            placeholder="请填写验证码宽度，如：300px，则填写300即可"
          />
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'tencent' && FormState.ak_from == 'alone'"
          label="腾讯云SecretId"
          name="tenc_secret_id"
        >
          <a-input v-model:value="FormState.tenc_secret_id" placeholder="请填写密钥ID">
            <template #suffix>
              <a href="https://console.cloud.tencent.com/cam/capi" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'tencent' && FormState.ak_from == 'alone'"
          label="腾讯云SecretKey"
          name="tenc_secret_key"
        >
          <a-input v-model:value="FormState.tenc_secret_key" placeholder="请填写访问密钥">
            <template #suffix>
              <a href="https://console.cloud.tencent.com/cam/capi" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item v-if="FormState.platform == 'tencent'" label="CaptchaAppId" name="tenc_app_id">
          <a-input v-model:value="FormState.tenc_app_id" placeholder="请填写CaptchaAppId">
            <template #suffix>
              <a href="https://console.cloud.tencent.com/captcha/graphical" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item
          v-if="FormState.platform == 'tencent'"
          label="AppSecretKey"
          name="tenc_app_secret"
        >
          <a-input v-model:value="FormState.tenc_app_secret" placeholder="请填写AppSecretKey">
            <template #suffix>
              <a href="https://console.cloud.tencent.com/captcha/graphical" target="_blank">
                <a-tooltip title="点击跳转官网获取">
                  <QuestionCircleOutlined />
                </a-tooltip>
              </a>
            </template>
          </a-input>
        </a-form-item>
        <a-form-item label="SecretKey" name="server_secret">
          <a-input-search
            v-model:value="FormState.server_secret"
            placeholder="点击右侧“获取密钥”按钮进行获取"
            enter-button="获取密钥"
            @search="resetSecret"
          />
        </a-form-item>
        <a-form-item label="状态" has-feedback required name="status">
          <a-radio-group v-model:value="FormState.status" name="status">
            <a-radio :key="1" :value="1">启用</a-radio>
            <a-radio :key="0" :value="0">不启用</a-radio>
          </a-radio-group>
        </a-form-item>
      </a-form>
    </a-drawer>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs, onMounted, ref, toRaw, watch } from 'vue'
import {
  Row,
  Col,
  Modal,
  Divider,
  Drawer,
  Card,
  Tooltip,
  TypographyText,
  Statistic,
  RadioGroup,
  RangePicker
} from 'ant-design-vue'
import {
  SyncOutlined,
  PlusOutlined,
  EditOutlined,
  CopyOutlined,
  DeleteOutlined,
  QuestionCircleOutlined,
  ExclamationCircleOutlined,
  DownOutlined
} from '@ant-design/icons-vue'
import { requestSuccess, requestFailed } from '@/utils/feedback'
import {
  delArtItem,
  getItemList,
  editData,
  getAllCaptcha,
  delCaptchaBatch,
  changeStatusItem
} from '@/api/captcha'
import { useRouter } from 'vue-router'
import { todayDate, randomString } from '@/utils/common'
import { getAllAkList } from '@/api/ak'

export default defineComponent({
  name: 'Captcha',
  components: {
    SyncOutlined,
    PlusOutlined,
    EditOutlined,
    TypographyText,
    CopyOutlined,
    ExclamationCircleOutlined,
    QuestionCircleOutlined,
    DownOutlined,
    DeleteOutlined,
    [Row.name]: Row,
    [Card.name]: Card,
    [Tooltip.name]: Tooltip,
    [RadioGroup.name]: RadioGroup,
    [RangePicker.name]: RangePicker,
    [Divider.name]: Divider,
    [Statistic.name]: Statistic,
    [Drawer.name]: Drawer,
    [Col.name]: Col
  },
  setup() {
    const formRef = ref()
    const router = useRouter()
    const state = reactive<any>({
      loading: true,
      drawerShow: false,
      today: todayDate(),
      akList: [],
      dataList: [],
      allCaptcheData: [],
      selectedRowKeys: [],
      selectedKeysPage: {},
      secretShow: {},
      totalData: {},
      searchText: '',
      allLineRender: '',
      singleLineRender: '',
      ticketLineRender: '',
      dataTime: '',
      allLine: ref(),
      singleLine: ref(),
      ticketLine: ref(),
      activeKey: ref('1'),
      listQuery: {
        pageNo: 1,
        pageSize: 15,
        date_range: [],
        date_range_format: [],
        date_num: -1
      },
      listQuerySingle: {
        app_id: '',
        date_range: [],
        date_range_format: [],
        date_num: 0
      },
      pagination: {
        pageSizeOptions: ['15', '30', '50'],
        showSizeChanger: true,
        total: 1,
        showTotal: (total) => `共 ${total} 条数据`,
        pageSize: 15,
        current: 1
      },
      labelCol: {
        xs: { span: 24 },
        sm: { span: 3 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 20 }
      },
      columns: [
        {
          title: '配置ID',
          dataIndex: '_id'
        },
        {
          title: '名称',
          dataIndex: 'title'
        },
        {
          title: '验证平台',
          dataIndex: 'platform_title'
        },
        {
          title: '创建时间',
          dataIndex: 'create_time'
        },
        {
          title: '状态',
          slots: { customRender: 'status' }
        },
        {
          title: '操作',
          width: '250px',
          slots: { customRender: 'action' }
        }
      ]
    })
    onMounted(() => {
      getDataList()
    })

    watch(
      () => state.activeKey,
      () => {
        if (state.activeKey == 1) {
          getDataList()
        } else {
          getAllCaptchaData()
        }
      }
    )
    function resetSecret() {
      FormState.server_secret = randomString(64)
    }
    function getAllCaptchaData() {
      getAllCaptcha({}).then((res) => {
        state.listQuerySingle.app_id = res[0].app_id
        state.allCaptcheData = res
      })
    }

    const FormState = reactive<any>({
      title: '',
      jdcloud_app_id: '',
      platform: '',
      status: '',
      type: ''
    })
    const FormRule = {
      title: [{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }],
      status: [{ required: true, message: '请选择验证场景', trigger: ['blur', 'change'] }],
      type: [{ required: true, message: '请选择验证渠道', trigger: ['blur', 'change'] }]
    }

    watch(
      () => FormState.platform,
      () => {
        getAkList()
        state.searchText = ''
      }
    )
    function getAkList() {
      getAllAkList({ platform: FormState.platform, title: state.searchText }).then((res) => {
        state.akList = res
      })
    }
    function searchInput(v) {
      state.searchText = v
      getAkList()
    }

    function handleTableChange(e) {
      state.loading = true
      state.pagination.pageSize = e.pageSize
      state.listQuery.pageSize = e.pageSize
      state.listQuery.pageNo = e.current
      state.pagination.current = e.current
      getDataList()
    }

    function reloadList() {
      state.loading = true
      state.listQuery.pageNo = 1
      state.pagination.current = 1
      getDataList()
    }

    function searchSubmit() {
      state.loading = true
      state.listQuery.pageNo = 1
      state.pagination.current = 1
      getDataList()
    }
    function captcha_edit(res) {
      for (let item in FormState) {
        FormState[item] = ''
      }
      for (let item in res) {
        FormState[item] = res[item]
      }
      state.drawerShow = true
    }
    function captcha_copy(res) {
      for (let item in FormState) {
        FormState[item] = ''
      }
      for (let item in res) {
        if (item != '_id' && item != 'server_secret') {
          let copyTips = item == 'title' ? ' - 复制' : ''
          FormState[item] = res[item] + copyTips
        }
      }
      state.drawerShow = true
    }
    function captcha_add() {
      for (let item in FormState) {
        FormState[item] = ''
      }
      state.drawerShow = true
    }

    function getDataList() {
      getItemList(state.listQuery).then((res) => {
        state.loading = false
        state.dataList = res
        for (let index = 0; index < res.data.length; index++) {
          const element = res.data[index]
          state.secretShow[element.app_id] = false
        }
        state.pagination.total = res.totalCount
      })
    }
    const addItem = () => {
      formRef.value
        .validate()
        .then(() => {
          editData(toRaw(FormState)).then((res) => {
            if (res.code === 200) {
              requestSuccess(res)
              formRef.value.resetFields()
              state.loading = true
              state.drawerShow = false
              reloadList()
            } else {
              requestFailed(res)
            }
          })
        })
        .catch(() => {
          return false
        })
    }
    function captcha_delete(data) {
      Modal.confirm({
        title: '确认删除此验证码?',
        content: '【' + data.title + '】',
        okType: 'danger',
        okText: '确认删除',
        onOk() {
          delArtItem({ id: data._id }).then((res) => {
            if (res.code === 200) {
              state.loading = true
              getDataList()
              requestSuccess(res)
            } else {
              requestFailed(res)
            }
          })
        }
      })
    }
    function changeStatus(status, data) {
      changeStatusItem({ id: data._id, status: status }).then((res) => {
        if (res.code === 200) {
          state.loading = true
          getDataList()
          requestSuccess(res)
        } else {
          requestFailed(res)
        }
      })
    }
    function deleteSelect() {
      Modal.confirm({
        title: '确认批量删除所选内容?',
        okType: 'danger',
        okText: '确认删除',
        onOk() {
          delCaptchaBatch({ ids: state.selectedRowKeys })
            .then((res) => {
              if (res.code === 200) {
                state.loading = true
                getDataList()
                requestSuccess(res)
              } else {
                requestFailed(res)
              }
            })
            .finally(() => {
              state.selectedRowKeys = []
            })
        }
      })
    }
    const onSelectChange = (selectedRowKeys) => {
      state.selectedKeysPage[state.listQuery.pageNo] = selectedRowKeys
      let nowList: any[] = []
      for (const key in state.selectedKeysPage) {
        nowList = nowList.concat(state.selectedKeysPage[key])
      }
      const uniqueList = [...new Set(nowList)]
      state.selectedRowKeys = uniqueList
    }
    return {
      ...toRefs(state),
      handleTableChange,
      deleteSelect,
      onSelectChange,
      reloadList,
      searchSubmit,
      captcha_delete,
      formRef,
      captcha_add,
      resetSecret,
      changeStatus,
      FormState,
      searchInput,
      captcha_edit,
      addItem,
      FormRule,
      captcha_copy,
      router,
      getDataList
    }
  }
})
</script>

<style scoped></style>
